home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 001 / pibt32s2.arc / PIBHOSTA.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1985-11-08  |  56.3 KB  |  1,249 lines

  1. OVERLAY PROCEDURE Emulate_Host;
  2.  
  3. (*----------------------------------------------------------------------*)
  4. (*               PibHost --- Host mode (mini-BBS) for PibTerm           *)
  5. (*----------------------------------------------------------------------*)
  6. (*                                                                      *)
  7. (*  Author:   Philip R. Burns                                           *)
  8. (*  Date:     July, 1985                                                *)
  9. (*  Version:  1.0  (July, 1985)                                         *)
  10. (*            1.1  (July, 1985)                                         *)
  11. (*            1.2  (August, 1985)                                       *)
  12. (*            2.0  (August, 1985)                                       *)
  13. (*            3.0  (October, 1985)                                      *)
  14. (*            3.2  (November, 1985)                                     *)
  15. (*                                                                      *)
  16. (*  Systems:  For MS-DOS on IBM PCs and close compatibles only.         *)
  17. (*            Note:  I have checked these on Zenith 151s under          *)
  18. (*                   MSDOS 2.1 and IBM PCs under PCDOS 2.0.             *)
  19. (*                                                                      *)
  20. (*  Overview: This overlay provides a simple host mode for use with     *)
  21. (*            PibTerm.  Facilities are provided for message leaving     *)
  22. (*            and file transfer.  This code can be used as a very       *)
  23. (*            simple remote bulletin board.  However, it lacks the      *)
  24. (*            security provisions needed for a genuine BBS, and is      *)
  25. (*            really intended to cover the need for a simple remote     *)
  26. (*            facility for a small private group of users.              *)
  27. (*                                                                      *)
  28. (*  Use:      This code assumes a Hayes-compatible modem.  You may need *)
  29. (*            to modify the code if your modem doesn't return verbal    *)
  30. (*            codes sufficient to determine the baud rate of the caller.*)
  31. (*            The modem is assumed to be set to answer the phone        *)
  32. (*            automatically.                                            *)
  33. (*                                                                      *)
  34. (*            To invoke host mode after entering PibTerm, enter Alt-W.  *)
  35. (*                                                                      *)
  36. (*            If you want the remote session echoed to the printer or   *)
  37. (*            captured to disk, then use the Alt-L and Alt-O commands   *)
  38. (*            before using Alt-W to invoke host mode.                   *)
  39. (*                                                                      *)
  40. (*            The following files are required above those normally     *)
  41. (*            used with PibTerm:                                        *)
  42. (*                                                                      *)
  43. (*              PIBTERM.USF  --- the user file.  A simple text file     *)
  44. (*                               containing the first name, last name,  *)
  45. (*                               and password for each authorized user. *)
  46. (*                               This file can be created using any     *)
  47. (*                               text editor that produces ascii files. *)
  48. (*                               The format is simply:                  *)
  49. (*                                                                      *)
  50. (*                                  firstname;lastname;password         *)
  51. (*                                                                      *)
  52. (*                               i.e., semicolons separating the first  *)
  53. (*                               name, last name, and password.         *)
  54. (*                                                                      *)
  55. (*                               This file MUST be created outside of   *)
  56. (*                               PibTerm;  there are no provisions for  *)
  57. (*                               a remote caller to get added to the    *)
  58. (*                               user file.                             *)
  59. (*                                                                      *)
  60. (*              PIBTERM.MSG ---  The message file.  This file is also   *)
  61. (*                               a simple ascii text file.  Message     *)
  62. (*                               header information is flagged by '=='  *)
  63. (*                               in columns one and two.  The end of a  *)
  64. (*                               message is marked by '== End' in       *)
  65. (*                               column one.  This file will be created *)
  66. (*                               by PibTerm if it doesn't exist when a  *)
  67. (*                               host session requires its presence.    *)
  68. (*                                                                      *)
  69. (*                               To remove messages, use a text editor  *)
  70. (*                               and just delete the header lines and   *)
  71. (*                               text for a message.  There are no      *)
  72. (*                               provisions for deleting messages       *)
  73. (*                               remotely.                              *)
  74. (*                                                                      *)
  75. (*              PIBTERM.XFR ---  The file transfer list.  This file     *)
  76. (*                               contains a list of files which may be  *)
  77. (*                               downloaded by a remote user.  Files    *)
  78. (*                               NOT on the transfer list cannot be     *)
  79. (*                               downloaded.                            *)
  80. (*                                                                      *)
  81. (*                               Also, a file with the same name as a   *)
  82. (*                               file on this list cannot be uploaded   *)
  83. (*                               by a remote user.  Further, any file   *)
  84. (*                               with PIBTERM as part of the name       *)
  85. (*                               can't be transferred, to prevent       *)
  86. (*                               a remote user from downloading the     *)
  87. (*                               user or comments files.                *)
  88. (*                                                                      *)
  89. (*                               The easiest way to create this file is *)
  90. (*                               to execute the DOS command:            *)
  91. (*                                                                      *)
  92. (*                                  DIR >PIBTERM.XFR                    *)
  93. (*                                                                      *)
  94. (*                               and then edit the resulting file using *)
  95. (*                               a text editor to remove unneeded lines *)
  96. (*                               and get the file names into 'name.ext' *)
  97. (*                               form as required by PibTerm.           *)
  98. (*                                                                      *)
  99. (*              PIBTERM.CMT ---  private comments file -- only readable *)
  100. (*                               by you.  The format is the same as the *)
  101. (*                               message file.                          *)
  102. (*                                                                      *)
  103. (*              PIBTERM.LOG ---  log file telling who logged on and     *)
  104. (*                               when they logged off.                  *)
  105. (*                                                                      *)
  106. (*            Note that all these files are simple sequential ascii     *)
  107. (*            files. This implies that they should be kept small for    *)
  108. (*            reasonable performance -- which is fine for a small group *)
  109. (*            of users.  This implementation does not provide good      *)
  110. (*            performance for a large group of users;  if you need that,*)
  111. (*            you should obtain a real BBS program designed to handle   *)
  112. (*            large numbers of users.                                   *)
  113. (*                                                                      *)
  114. (*                                                                      *)
  115. (*----------------------------------------------------------------------*)
  116. (*                                                                      *)
  117. (*                            Restriction                               *)
  118. (*                            -----------                               *)
  119. (*                                                                      *)
  120. (*           You may use this code only for NON COMMERCIAL purposes     *)
  121. (*           unless you explicitly obtain my permission.  I take a dim  *)
  122. (*           view of others making money on my work and those of other  *)
  123. (*           people whose code I've inserted here.                      *)
  124. (*                                                                      *)
  125. (*           Please feel free to add new features.  I wrote this        *)
  126. (*           program to give people a useful and usable basic terminal  *)
  127. (*           facility, and to show how Turbo Pascal can be used for     *)
  128. (*           asynchronous communications, menu display, windowing, and  *)
  129. (*           so on.  I hope that you find this program useful -- and,   *)
  130. (*           if you expand upon it, please upload your extensions so    *)
  131. (*           that all of us can enjoy them!                             *)
  132. (*                                                                      *)
  133. (*----------------------------------------------------------------------*)
  134. (*                                                                      *)
  135. (*           Suggestions for improvements or corrections are welcome.   *)
  136. (*           Please leave messages on Gene Plantz's BBS (312) 882 4145  *)
  137. (*           or Ron Fox's BBS (312) 940 6496.                           *)
  138. (*                                                                      *)
  139. (*----------------------------------------------------------------------*)
  140.  
  141. (*----------------------------------------------------------------------*)
  142. (*                    Global host mode variables                        *)
  143. (*----------------------------------------------------------------------*)
  144.  
  145. CONST
  146.    MaxUsers      = 20              (* Maximum number of users supported *);
  147.    Page_Size     = 23              (* No. lines per screen for display  *);
  148.    Max_Login_Try = 3               (* Max. number of tries for login    *);
  149.  
  150. TYPE                               (* Information about a user *)
  151.  
  152.    User_Record = RECORD
  153.                     First_Name: STRING[20];
  154.                     Last_Name : STRING[20];
  155.                     Password  : STRING[10];
  156.                  END;
  157.  
  158. VAR
  159.  
  160.    Done           : BOOLEAN        (* If session complete        *);
  161.    Really_Done    : BOOLEAN        (* To leave host mode         *);
  162.  
  163.    Kbd_Input      : BOOLEAN        (* Input found at host keybrd *);
  164.    Fname          : ShortStr       (* First name of caller       *);
  165.    Lname          : ShortStr       (* Last name of caller        *);
  166.    PassWord       : ShortStr       (* Password to access system  *);
  167.    First_Time     : BOOLEAN        (* If first time host mode up *);
  168.    Recipient_Name : AnyStr         (* Name for message reception *);
  169.    Message_Subject: AnyStr         (* Subject of message         *);
  170.    Message_Line   : AnyStr         (* Text line for message      *);
  171.  
  172.    CR_LF_Host     : STRING[2]      (* CR or CR+LF                *);
  173.    Expert_On      : BOOLEAN        (* TRUE to use short menus    *);
  174.  
  175.    User_File      : Text_File      (* Password file              *);
  176.    Message_File   : Text_File      (* Message file               *);
  177.    Comments_File  : Text_File      (* Comments file              *);
  178.    Log_File       : Text_File      (* Log file                   *);
  179.  
  180.                                    (* User list *)
  181.  
  182.    User_List      : ARRAY[1 .. MaxUsers] OF User_Record;
  183.  
  184.    NUsers         : INTEGER        (* Number of active users *);
  185.  
  186.    Cur_User       : INTEGER        (* Current user           *);
  187.    Cur_User_Name  : AnyStr         (* Current user's name    *);
  188.  
  189.    NMessages      : INTEGER        (* Number of messages     *);
  190.  
  191.    Local_Host     : BOOLEAN        (* TRUE if local host session *);
  192.    Host_Section   : CHAR           (* Which section are we in?   *);
  193.  
  194. (*----------------------------------------------------------------------*)
  195. (*        Host_Carrier_Detect --- Check for carrier or local mode       *)
  196. (*----------------------------------------------------------------------*)
  197.  
  198. FUNCTION Host_Carrier_Detect : BOOLEAN;
  199.  
  200. (*----------------------------------------------------------------------*)
  201. (*                                                                      *)
  202. (*     Function:  Host_Carrier_Detect                                   *)
  203. (*                                                                      *)
  204. (*     Purpose:   Reports on carrier detect/local host mode status      *)
  205. (*                                                                      *)
  206. (*     Calling sequence:                                                *)
  207. (*                                                                      *)
  208. (*        Carrier := Host_Carrier_Detect : BOOLEAN;                     *)
  209. (*                                                                      *)
  210. (*           Carrier --- set TRUE if local host session, or if          *)
  211. (*                       carrier detected for remote session.           *)
  212. (*                                                                      *)
  213. (*----------------------------------------------------------------------*)
  214.  
  215. BEGIN (* Host_Carrier_Detect *)
  216.  
  217.    Host_Carrier_Detect := FALSE;
  218.  
  219.    IF Local_Host THEN
  220.       Host_Carrier_Detect := TRUE
  221.    ELSE
  222.       Host_Carrier_Detect := Async_Carrier_Detect;
  223.  
  224. END   (* Host_Carrier_Detect *);
  225.  
  226. (*----------------------------------------------------------------------*)
  227. (*        Host_Send  ---  Send character to port/screen in host mode    *)
  228. (*----------------------------------------------------------------------*)
  229.  
  230. PROCEDURE Host_Send( Ch : CHAR );
  231.  
  232. (*----------------------------------------------------------------------*)
  233. (*                                                                      *)
  234. (*     Procedure:  Host_Send                                            *)
  235. (*                                                                      *)
  236. (*     Purpose:    Sends character to comm port and/or screen           *)
  237. (*                                                                      *)
  238. (*     Calling sequence:                                                *)
  239. (*                                                                      *)
  240. (*        Host_Send( Ch : CHAR );                                       *)
  241. (*                                                                      *)
  242. (*           Ch --- character to be sent out                            *)
  243. (*                                                                      *)
  244. (*     Remarks:  If local host session, character is NOT sent out port. *)
  245. (*                                                                      *)
  246. (*----------------------------------------------------------------------*)
  247.  
  248. BEGIN (* Host_Send *)
  249.  
  250.    IF ( NOT Local_Host ) THEN
  251.       Async_Send( Ch );
  252.  
  253.    WRITE( Ch );
  254.  
  255. END   (* Host_Send *);
  256.  
  257. (*----------------------------------------------------------------------*)
  258. (*   Host_Send_String  ---  Send string to port/screen in host mode     *)
  259. (*----------------------------------------------------------------------*)
  260.  
  261. PROCEDURE Host_Send_String( S : AnyStr );
  262.  
  263. (*----------------------------------------------------------------------*)
  264. (*                                                                      *)
  265. (*     Procedure:  Host_Send_String                                     *)
  266. (*                                                                      *)
  267. (*     Purpose:    Sends string to comm port and/or screen              *)
  268. (*                                                                      *)
  269. (*     Calling sequence:                                                *)
  270. (*                                                                      *)
  271. (*        Host_Send_String( S : AnyStr );                               *)
  272. (*                                                                      *)
  273. (*           S --- character to be sent out                             *)
  274. (*                                                                      *)
  275. (*     Remarks:  If local host session, string is NOT sent out port.    *)
  276. (*                                                                      *)
  277. (*----------------------------------------------------------------------*)
  278.  
  279. BEGIN (* Host_Send_String *)
  280.  
  281.    IF ( NOT Local_Host ) THEN
  282.       Async_Send_String( S );
  283.  
  284.    WRITE( S );
  285.  
  286.    IF Printer_On THEN
  287.       WRITE( Lst, S );
  288.  
  289.    IF Capture_On THEN
  290.       WRITE( Capture_File , S );
  291.  
  292. END   (* Host_Send_String *);
  293.  
  294. (*----------------------------------------------------------------------*)
  295. (*   Host_Send_String_With_CR --- Append CR or CR+LF and send string    *)
  296. (*----------------------------------------------------------------------*)
  297.  
  298. PROCEDURE Host_Send_String_With_CR( S : AnyStr );
  299.  
  300. (*----------------------------------------------------------------------*)
  301. (*                                                                      *)
  302. (*     Procedure: Host_Send_String_With_CR                              *)
  303. (*                                                                      *)
  304. (*     Purpose:   Appends end-of-line characters to string and sends    *)
  305. (*                it out over communications port.                      *)
  306. (*                                                                      *)
  307. (*     Calling sequence:                                                *)
  308. (*                                                                      *)
  309. (*        Host_Send_String_With_CR( S: AnyStr );                        *)
  310. (*                                                                      *)
  311. (*           S --- string to be sent out.                               *)
  312. (*                                                                      *)
  313. (*     Remarks:                                                         *)
  314. (*                                                                      *)
  315. (*        The end-of-line characters are either a CR or a CR+LF,        *)
  316. (*        depending upon the choice made by the user at login time.     *)
  317. (*                                                                      *)
  318. (*----------------------------------------------------------------------*)
  319.  
  320. BEGIN (* Host_Send_String_With_CR *)
  321.  
  322.    IF ( NOT Local_Host ) THEN
  323.       Async_Send_String( S + CR_LF_Host );
  324.  
  325.    WRITELN( S );
  326.  
  327.    IF Printer_On THEN
  328.       WRITELN( Lst, S );
  329.  
  330.    IF Capture_On THEN
  331.       WRITELN( Capture_File , S );
  332.  
  333. END   (* Host_Send_String_With_CR *);
  334.  
  335. (*----------------------------------------------------------------------*)
  336. (*    Host_Send_String_And_Echo --- Send string and echo it to screen   *)
  337. (*----------------------------------------------------------------------*)
  338.  
  339. PROCEDURE Host_Send_String_And_Echo( S : AnyStr );
  340.  
  341. (*----------------------------------------------------------------------*)
  342. (*                                                                      *)
  343. (*     Procedure: Host_Send_String_And_Echo                             *)
  344. (*                                                                      *)
  345. (*     Purpose:   Send string out com port and echo to screen           *)
  346. (*                                                                      *)
  347. (*     Calling sequence:                                                *)
  348. (*                                                                      *)
  349. (*        Host_Send_String_And_Echo( S: AnyStr );                       *)
  350. (*                                                                      *)
  351. (*           S --- string to be sent out and echoed.                    *)
  352. (*                                                                      *)
  353. (*----------------------------------------------------------------------*)
  354.  
  355. BEGIN (* Host_Send_String_And_Echo *)
  356.  
  357.    IF ( NOT Local_Host ) THEN
  358.       Async_Send_String( S );
  359.  
  360.    WRITE( S );
  361.  
  362.    IF Printer_On THEN
  363.       WRITE( Lst, S );
  364.  
  365.    IF Capture_On THEN
  366.       WRITE( Capture_File , S );
  367.  
  368. END   (* Host_Send_String_And_Echo *);
  369.  
  370. (*----------------------------------------------------------------------*)
  371. (*    Host_Prompt_And_Read_String --- Get string from remote and echo   *)
  372. (*----------------------------------------------------------------------*)
  373.  
  374. PROCEDURE Host_Prompt_And_Read_String(      Prompt : AnyStr;
  375.                                         VAR S      : AnyStr;
  376.                                             Echo   : BOOLEAN );
  377.  
  378. (*----------------------------------------------------------------------*)
  379. (*                                                                      *)
  380. (*     Procedure: Host_Prompt_And_Read_String                           *)
  381. (*                                                                      *)
  382. (*     Purpose:   Issues prompt to remote user, reads response, and     *)
  383. (*                echos response.                                       *)
  384. (*                                                                      *)
  385. (*     Calling sequence:                                                *)
  386. (*                                                                      *)
  387. (*        Host_Prompt_And_Read_String(      Prompt : AnyStr;            *)
  388. (*                                      VAR S      : AnyStr;            *)
  389. (*                                          Echo   : BOOLEAN );         *)
  390. (*                                                                      *)
  391. (*           Prompt --- prompt string to be issued.                     *)
  392. (*                      If null, no prompt is issued.                   *)
  393. (*           S      --- resulting string received from remote user.     *)
  394. (*           Echo   --- TRUE to echo characters as they are read;       *)
  395. (*                      FALSE to echo characters as '.'s.  This is      *)
  396. (*                      useful for getting passwords.                   *)
  397. (*                                                                      *)
  398. (*----------------------------------------------------------------------*)
  399.  
  400. VAR
  401.    Ch      : CHAR;
  402.    GotChar : BOOLEAN;
  403.    XPos    : INTEGER;
  404.    Rem_Ch  : CHAR;
  405.  
  406. BEGIN (* Host_Prompt_And_Read_String *)
  407.  
  408.                                    (* Send prompt to remote user *)
  409.    IF LENGTH( Prompt ) > 0 THEN
  410.       Host_Send_String_And_Echo( Prompt );
  411.  
  412.    Ch      := CHR( 0 );
  413.    S       := '';
  414.    XPos    := WhereX;
  415.                                    (* Get response string        *)
  416.    REPEAT
  417.  
  418.       GotChar := FALSE;
  419.  
  420.       IF KeyPressed THEN
  421.          BEGIN
  422.             READ( Kbd, Ch );
  423.             GotChar := TRUE;
  424.          END;
  425.  
  426.       IF Async_Receive( Rem_Ch ) THEN
  427.          BEGIN
  428.             Ch      := Rem_Ch;
  429.             GotChar := TRUE;
  430.          END;
  431.  
  432.       IF GotChar THEN
  433.          IF Ch <> CHR( CR ) THEN
  434.             IF Ch = ^H THEN
  435.                BEGIN  (* Backspace *)
  436.                   IF WhereX > Xpos THEN
  437.                      BEGIN
  438.                         Host_Send( Ch  );
  439.                         Host_Send( ' ' );
  440.                         Host_Send( Ch  );
  441.                         IF LENGTH( S ) > 1 THEN
  442.                            S := COPY( S, 1, LENGTH( S ) - 1 )
  443.                         ELSE
  444.                            S := '';
  445.                      END;
  446.                END   (* Backspace *)
  447.             ELSE
  448.                BEGIN
  449.                   S := S + Ch;
  450.                   IF Echo THEN
  451.                      Host_Send( Ch )
  452.                   ELSE
  453.                      Host_Send( '.' );
  454.                END;
  455.  
  456.    UNTIL ( Ch = CHR( CR ) ) OR ( NOT Host_Carrier_Detect );
  457.  
  458.                                    (* CR ends line *)
  459.    IF Host_Carrier_Detect THEN
  460.       BEGIN
  461.  
  462.          WRITELN;
  463.  
  464.          IF Printer_On THEN
  465.             WRITELN( Lst , S );
  466.  
  467.          IF Capture_On THEN
  468.             WRITELN( Capture_File , S );
  469.  
  470.       END;
  471.  
  472. END   (* Host_Prompt_And_Read_String *);
  473.  
  474. (*----------------------------------------------------------------------*)
  475. (*            Page_Sysop --- Page sysop to enter gossip mode            *)
  476. (*----------------------------------------------------------------------*)
  477.  
  478. PROCEDURE Page_Sysop( VAR Sysop_Found : BOOLEAN );
  479.  
  480. (*----------------------------------------------------------------------*)
  481. (*                                                                      *)
  482. (*     Procedure:  Page_Sysop                                           *)
  483. (*                                                                      *)
  484. (*     Purpose:    Pages Sysop to enter gossip mode.                    *)
  485. (*                                                                      *)
  486. (*     Calling Sequence:                                                *)
  487. (*                                                                      *)
  488. (*        Page_Sysop( VAR Sysop_Found : BOOLEAN );                      *)
  489. (*                                                                      *)
  490. (*           Sysop_Found --- TRUE if sysop responds.                    *)
  491. (*                                                                      *)
  492. (*     Remarks:                                                         *)
  493. (*                                                                      *)
  494. (*        If silent mode is on (Alt_M) then this page is not performed. *)
  495. (*                                                                      *)
  496. (*----------------------------------------------------------------------*)
  497.  
  498. VAR
  499.    Timer: REAL;
  500.    I    : INTEGER;
  501.    Ch   : CHAR;
  502.  
  503. BEGIN (* Page_Sysop *)
  504.  
  505.    Host_Send_String_With_CR(' ');
  506.  
  507.    Sysop_Found := FALSE;
  508.  
  509.    IF ( NOT Silent_Mode ) THEN
  510.       BEGIN
  511.  
  512.          Host_Send_String_With_CR('Summoning Sysop ...');
  513.  
  514.          Timer := 30;
  515.  
  516.          REPEAT
  517.  
  518.             FOR I := 1 TO 5 DO
  519.                WRITE( CHR( BELL ) );
  520.  
  521.             IF KeyPressed THEN
  522.                BEGIN
  523.                   READ( Kbd, Ch );
  524.                   IF ( Ch = CHR( ESC ) ) AND KeyPressed THEN
  525.                      READ( Kbd , Ch );
  526.                   Sysop_Found := TRUE;
  527.                END;
  528.  
  529.             DELAY( One_Second_Delay );
  530.  
  531.             Timer := Timer - 1.0;
  532.  
  533.          UNTIL ( Timer <= 0.0 ) OR ( Sysop_Found );
  534.  
  535.       END
  536.    ELSE
  537.       Host_Send_String_With_CR('Sysop not available, gossip cancelled.');
  538.  
  539. END   (* Page_Sysop *);
  540.  
  541. (*----------------------------------------------------------------------*)
  542. (*           List_Prompt --- prompt for end-of-screen                   *)
  543. (*----------------------------------------------------------------------*)
  544.  
  545. PROCEDURE List_Prompt( VAR List_Count : INTEGER; VAR List_Done : BOOLEAN );
  546.  
  547. (*----------------------------------------------------------------------*)
  548. (*                                                                      *)
  549. (*     Procedure:  List_Prompt                                          *)
  550. (*                                                                      *)
  551. (*     Purpose:    Issues end-of-screen prompt for view routines        *)
  552. (*                                                                      *)
  553. (*     Calling Sequence:                                                *)
  554. (*                                                                      *)
  555. (*        List_Prompt( VAR List_Count : INTEGER;                        *)
  556. (*                     VAR List_Done  : BOOLEAN );                      *)
  557. (*                                                                      *)
  558. (*           List_Done  --- TRUE if Stop option selected here           *)
  559. (*           List_Count --- Count of lines per panel.  May be changed   *)
  560. (*                          here if C option selected.                  *)
  561. (*                                                                      *)
  562. (*     Calls:   RvsVideoOn                                              *)
  563. (*              RvsVideoOff                                             *)
  564. (*                                                                      *)
  565. (*     Called by:                                                       *)
  566. (*                                                                      *)
  567. (*        List_Files_For_Transfer                                       *)
  568. (*        Read_Messages                                                 *)
  569. (*                                                                      *)
  570. (*----------------------------------------------------------------------*)
  571.  
  572. VAR
  573.    List_Char : CHAR;
  574.  
  575. BEGIN (* List_Prompt *)
  576.  
  577.    List_Count := List_Count + 1;
  578.  
  579.    IF List_Count > Page_Size THEN
  580.       BEGIN (* Do end of screen prompt *)
  581.  
  582.          REPEAT
  583.  
  584.             Host_Send_String_And_Echo('Enter <CR> to continue, S to stop, ' +
  585.                                           'C to continue non-stop: ');
  586.  
  587.             REPEAT
  588.             UNTIL ( Async_Receive( List_Char ) OR KeyPressed OR
  589.                     ( NOT Host_Carrier_Detect ) );
  590.  
  591.             IF KeyPressed THEN
  592.                READ( KBD, List_Char );
  593.  
  594.             IF List_Char = CHR( CR ) THEN
  595.                List_Char := ' ';
  596.  
  597.             Host_Send_String_With_CR( List_Char );
  598.  
  599.             IF Printer_On THEN
  600.                WRITELN( Lst , List_Char );
  601.             IF Capture_On THEN
  602.                WRITELN( Capture_File , List_Char );
  603.  
  604.             List_Char := UpCase( List_Char );
  605.  
  606.          UNTIL ( List_Char IN ['S', 'C', ' '] ) OR ( NOT Host_Carrier_Detect );
  607.  
  608.          CASE List_Char Of
  609.             'C':  List_Count := -MaxInt;
  610.             'S':  List_Done  := TRUE;
  611.             ' ':  List_Count := 1;
  612.             ELSE
  613.                   ;
  614.          END (* CASE *);
  615.  
  616.       END (* Do end of screen prompt *);
  617.  
  618. END  (* List_Prompt *);
  619.  
  620. (*----------------------------------------------------------------------*)
  621. (*                   Gossip_Mode --- Enter PibTerm gossip mode          *)
  622. (*----------------------------------------------------------------------*)
  623.  
  624. PROCEDURE Gossip_Mode;
  625.  
  626. (*----------------------------------------------------------------------*)
  627. (*                                                                      *)
  628. (*     Procedure:  Gossip_Mode                                          *)
  629. (*                                                                      *)
  630. (*     Purpose:    Allows "conversation" with remote user.              *)
  631. (*                                                                      *)
  632. (*     Calling Sequence:                                                *)
  633. (*                                                                      *)
  634. (*        Gossip_Mode;                                                  *)
  635. (*                                                                      *)
  636. (*     Remarks:                                                         *)
  637. (*                                                                      *)
  638. (*         This gossip mode feature does not use a split screen.        *)
  639. (*                                                                      *)
  640. (*----------------------------------------------------------------------*)
  641.  
  642. VAR
  643.    Gossip_Done : BOOLEAN           (* TRUE to exit back to host mode       *);
  644.    Ch          : CHAR              (* Character read/written               *);
  645.    Bozo        : BOOLEAN;
  646.  
  647. BEGIN (* Gossip_Mode *)
  648.  
  649.    Host_Send_String_With_CR(' ');
  650.    Host_Send_String_With_CR('Entering gossip mode ... ');
  651.    WRITELN('Enter Ctrl-C to exit gossip mode.');
  652.  
  653.    Gossip_Done := FALSE;
  654.                                    (* Loop over input until done *)
  655.    WHILE ( NOT Gossip_Done ) DO
  656.       BEGIN
  657.                                    (* Check if XOFF needs to be sent *)
  658.          Async_Buffer_Full;
  659.                                    (* Check for character typed at keyboard *)
  660.          IF KeyPressed THEN
  661.             BEGIN
  662.  
  663.                READ( Kbd , Ch );
  664.  
  665.                IF ( ORD( Ch ) = ESC ) AND KeyPressed THEN
  666.                   BEGIN
  667.                      READ( Kbd, Ch );
  668.                      IF ( ORD( Ch ) = F1 ) THEN
  669.                         Ch := CHR( 3 )
  670.                      ELSE IF ( ORD( Ch ) = F2 ) THEN
  671.                         BEGIN
  672.                            Ch := CHR( 3 );
  673.                            Done := TRUE;
  674.                         END;
  675.                   END;
  676.  
  677.                CASE ORD( Ch ) OF
  678.  
  679.                     3:  Gossip_Done := TRUE;
  680.  
  681.                   ESC:  IF KeyPressed THEN
  682.                            BEGIN
  683.                               Process_Command( Ch, FALSE, PibTerm_Command );
  684.                               IF PibTerm_Command <> Null_Command THEN
  685.                                  Execute_Command( PibTerm_Command, Bozo, FALSE );
  686.                            END
  687.                         ELSE
  688.                            BEGIN
  689.                               IF Local_Echo THEN WRITE( Ch );
  690.                               Async_Send( Ch );
  691.                            END;
  692.  
  693.  
  694.                   BS:   BEGIN
  695.                            Ch := BS_Char;
  696.                            Host_Send( Ch );
  697.                            IF Printer_On THEN
  698.                               WRITE( Lst , Ch );
  699.                            IF Capture_On THEN
  700.                               WRITE( Capture_File , Ch );
  701.                         END;
  702.  
  703.                   DEL:  BEGIN
  704.                            Ch := Ctrl_BS_Char;
  705.                            Host_Send( Ch );
  706.                            IF Printer_On THEN
  707.                               WRITE( Lst , Ch );
  708.                            IF Capture_On THEN
  709.                               WRITE( Capture_File , Ch );
  710.                         END;
  711.  
  712.                   CR:   BEGIN
  713.                            Host_Send_String( CR_LF_Host );
  714.                            IF Printer_On THEN
  715.                               WRITELN( Lst );
  716.                            IF Capture_On THEN
  717.                               WRITELN( Capture_File );
  718.                         END;
  719.  
  720.                   ELSE
  721.                         BEGIN
  722.                            Host_Send( Ch );
  723.                            IF Printer_On THEN
  724.                               WRITE( Lst , Ch );
  725.                            IF Capture_On THEN
  726.                               WRITE( Capture_File , Ch );
  727.                         END;
  728.  
  729.                END (* CASE ORD( Ch ) *);
  730.  
  731.             END;
  732.  
  733.          IF Async_Receive( Ch ) THEN
  734.             BEGIN
  735.                IF Ch = CHR( CR ) THEN
  736.                   BEGIN
  737.                      IF Printer_On THEN
  738.                         WRITELN( Lst );
  739.                      IF Capture_On THEN
  740.                         WRITELN( Capture_File );
  741.                      Host_Send_String( CR_LF_Host );
  742.                   END
  743.                ELSE
  744.                   Host_Send( Ch );
  745.             END;
  746.  
  747.       END;
  748.  
  749. END   (* Gossip_Mode *);
  750.  
  751. (*----------------------------------------------------------------------*)
  752. (*                Start of host mode overlay section one                *)
  753. (*----------------------------------------------------------------------*)
  754.  
  755. CONST
  756.    Start_Host_Overlay_One = 1;
  757.  
  758. (*----------------------------------------------------------------------*)
  759. (*  Process_File_Transfer_Commands --- Process file transfer commands   *)
  760. (*----------------------------------------------------------------------*)
  761.  
  762. OVERLAY PROCEDURE Process_File_Transfer_Commands( VAR Done: BOOLEAN;
  763.                                                   VAR Back: BOOLEAN );
  764.  
  765. (*----------------------------------------------------------------------*)
  766. (*                                                                      *)
  767. (*     Procedure:  Process_File_Transfer_Commands                       *)
  768. (*                                                                      *)
  769. (*     Purpose:    Controls processing of file transfer commands.       *)
  770. (*                                                                      *)
  771. (*     Calling Sequence:                                                *)
  772. (*                                                                      *)
  773. (*        Process_File_Transfer_Commands( VAR Done: BOOLEAN;            *)
  774. (*                                        VAR Back: BOOLEAN );          *)
  775. (*                                                                      *)
  776. (*           Done --- set TRUE if quit command entered or carrier       *)
  777. (*                    dropped.                                          *)
  778. (*           Back --- set TRUE if return to main menu requested.        *)
  779. (*                                                                      *)
  780. (*----------------------------------------------------------------------*)
  781.  
  782. VAR
  783.    Ch:        CHAR;
  784.  
  785. (*----------------------------------------------------------------------*)
  786. (*      Display_Xfer_Commands --- Display file transfer commands        *)
  787. (*----------------------------------------------------------------------*)
  788.  
  789. PROCEDURE Display_Xfer_Commands;
  790.  
  791. (*----------------------------------------------------------------------*)
  792. (*                                                                      *)
  793. (*     Procedure: Display_Xfer_Commands                                 *)
  794. (*                                                                      *)
  795. (*     Purpose:   Displays menu of PibTerm file transfer commands and   *)
  796. (*                prompts for command entry.                            *)
  797. (*                                                                      *)
  798. (*     Calling sequence:                                                *)
  799. (*                                                                      *)
  800. (*        Display_Xfer_Commands;                                        *)
  801. (*                                                                      *)
  802. (*----------------------------------------------------------------------*)
  803.  
  804. BEGIN (* Display_Xfer_Commands *)
  805.  
  806.    IF ( NOT Expert_On ) THEN
  807.       BEGIN
  808.          Host_Send_String_With_CR('======================================================');
  809.          Host_Send_String_With_CR('=        PibTerm Host Mode File Transfer Menu        =');
  810.          Host_Send_String_With_CR('======================================================');
  811.          Host_Send_String_With_CR(' ');
  812.          Host_Send_String_With_CR('     U=Upload file');
  813.          Host_Send_String_With_CR('     D=Download file');
  814.          Host_Send_String_With_CR('     L=List files for transfer');
  815.          Host_Send_String_With_CR('     M=Return to main menu');
  816.          Host_Send_String_With_CR('     Q=Quit and logoff');
  817.          Host_Send_String_With_CR('     X=Expert mode');
  818.          Host_Send_String_With_CR(' ');
  819.          Host_Send_String_With_CR('======================================================');
  820.          Host_Send_String_With_CR(' ');
  821.          Host_Send_String_And_Echo('Enter command ? ');
  822.       END
  823.    ELSE
  824.       BEGIN
  825.          Host_Send_String_With_CR(' ');
  826.          Host_Send_String_And_Echo('Xfer (U,D,L,M,Q,X) ? ');
  827.       END;
  828.  
  829. END   (* Display_Xfer_Commands *);
  830.  
  831.  
  832. (*----------------------------------------------------------------------*)
  833. (*    List_Files_For_Transfer --- List files available for transfer     *)
  834. (*----------------------------------------------------------------------*)
  835.  
  836. PROCEDURE List_Files_For_Transfer;
  837.  
  838. (*----------------------------------------------------------------------*)
  839. (*                                                                      *)
  840. (*     Procedure: List_Files_For_Transfer                               *)
  841. (*                                                                      *)
  842. (*     Purpose:   Displays files available for transfer.                *)
  843. (*                                                                      *)
  844. (*     Calling sequence:                                                *)
  845. (*                                                                      *)
  846. (*        List_Files_For_Transfer;                                      *)
  847. (*                                                                      *)
  848. (*                                                                      *)
  849. (*     Remarks:                                                         *)
  850. (*                                                                      *)
  851. (*        This procedure sends the contents of the PIBTERM.XFR file to  *)
  852. (*        the remote user.                                              *)
  853. (*                                                                      *)
  854. (*----------------------------------------------------------------------*)
  855.  
  856. VAR
  857.    LCount    : INTEGER;
  858.    LDone     : BOOLEAN;
  859.    XFer_Line : AnyStr;
  860.  
  861. BEGIN (* List_Files_For_Transfer *)
  862.                                    (* Open xferlist file *)
  863.  
  864.    ASSIGN( Xfer_List_File , Home_Dir + 'PIBTERM.XFR' );
  865.       (*$I-*)
  866.    RESET( Xfer_List_File );
  867.       (*$I+*)
  868.                                    (* If not there, no transfer possible *)
  869.    IF Int24Result <> 0 THEN
  870.       BEGIN
  871.          Host_Send_String( CR_LF_Host );
  872.          Host_Send_String_With_CR('No files available for transfer.');
  873.       END
  874.    ELSE                            (* If there, list it *)
  875.       BEGIN
  876.  
  877.          LCount := 2;
  878.          LDone  := FALSE;
  879.  
  880.          Host_Send_String( CR_LF_Host );
  881.          Host_Send_String_With_CR('List of files available for transfer: ');
  882.          Host_Send_String_With_CR(' ');
  883.  
  884.          List_Prompt( LCount , LDone );
  885.  
  886.          REPEAT
  887.  
  888.             READLN( Xfer_List_File , Xfer_Line );
  889.  
  890.             Host_Send_String_With_CR( Xfer_Line );
  891.  
  892.             List_Prompt( LCount , LDone );
  893.  
  894.          UNTIL ( EOF( Xfer_List_File ) OR LDone );
  895.  
  896.       END;
  897.  
  898.       (*$I-*)
  899.    CLOSE( Xfer_List_File )
  900.       (*$I+*)
  901.  
  902. END   (* List_Files_For_Transfer *);
  903.  
  904. (*----------------------------------------------------------------------*)
  905. (*        Search_Xfer_List --- Search transfer list for file name       *)
  906. (*----------------------------------------------------------------------*)
  907.  
  908. FUNCTION Search_Xfer_List( File_Name : AnyStr ) : BOOLEAN;
  909.  
  910. (*----------------------------------------------------------------------*)
  911. (*                                                                      *)
  912. (*     Function:  Search_Xfer_List                                      *)
  913. (*                                                                      *)
  914. (*     Purpose:   Searches transfer list for given file name.           *)
  915. (*                                                                      *)
  916. (*     Calling sequence:                                                *)
  917. (*                                                                      *)
  918. (*        Found := Search_Xfer_List( File_Name: AnyStr ) : BOOLEAN;     *)
  919. (*                                                                      *)
  920. (*           File_Name --- file name to look for.                       *)
  921. (*           Found     --- TRUE if file on transfer list, else FALSE.   *)
  922. (*                                                                      *)
  923. (*     Remarks:                                                         *)
  924. (*                                                                      *)
  925. (*        This procedure searches the contents of the PIBTERM.XFR file. *)
  926. (*                                                                      *)
  927. (*----------------------------------------------------------------------*)
  928.  
  929. VAR
  930.    SDone     : BOOLEAN;
  931.    XFer_Line : AnyStr;
  932.  
  933. BEGIN (* Search_Xfer_List *)
  934.  
  935.    Host_Send_String( CR_LF_Host );
  936.  
  937.    Host_Send_String_With_CR('Scanning file list ... ');
  938.  
  939.    Search_Xfer_List := Scan_Xfer_List( File_Name );
  940.  
  941. END   (* Search_Xfer_List *);
  942.  
  943. (*----------------------------------------------------------------------*)
  944. (*        Display_Xfer_Protocols --- Display file xfer protocols        *)
  945. (*----------------------------------------------------------------------*)
  946.  
  947. PROCEDURE Display_Xfer_Protocols;
  948.  
  949. (*----------------------------------------------------------------------*)
  950. (*                                                                      *)
  951. (*     Procedure: Display_Xfer_Protocols;                               *)
  952. (*                                                                      *)
  953. (*     Purpose:   Displays available file transfer protocols.           *)
  954. (*                                                                      *)
  955. (*     Calling sequence:                                                *)
  956. (*                                                                      *)
  957. (*        Display_Xfer_Protocols;                                       *)
  958. (*                                                                      *)
  959. (*----------------------------------------------------------------------*)
  960.  
  961. BEGIN (* Display_Xfer_Protocols *)
  962.  
  963.    Host_Send_String( CR_LF_Host );
  964.    Host_Send_String_With_CR('Available transfer protocols are: ');
  965.    Host_Send_String_With_CR(' ');
  966.    Host_Send_String_With_CR('   A    Ascii');
  967.    Host_Send_String_With_CR('   X    Xmodem CheckSum');
  968.    Host_Send_String_With_CR('   XC   Xmodem CRC');
  969.    Host_Send_String_With_CR('   Y    Ymodem');
  970.    Host_Send_String_With_CR('   YB   Ymodem Batch');
  971.    Host_Send_String_With_CR('   T    Telink');
  972.    Host_Send_String_With_CR('   M    Modem7 Batch Checksum');
  973.    Host_Send_String_With_CR('   MC   Modem7 Batch CRC');
  974.    Host_Send_String_With_CR('   K    Kermit (Text file)');
  975.    Host_Send_String_With_CR('   KB   Kermit (Binary file)');
  976.    Host_Send_String_With_CR('   Q    Quit transfer');
  977.  
  978. END   (* Display_Xfer_Protocols *);
  979.  
  980. (*----------------------------------------------------------------------*)
  981. (*              Get_Xfer_Protocol --- Get file xfer protocol            *)
  982. (*----------------------------------------------------------------------*)
  983.  
  984. FUNCTION Get_Xfer_Protocol : Transfer_Type;
  985.  
  986. (*----------------------------------------------------------------------*)
  987. (*                                                                      *)
  988. (*     Function:  Get_Xfer_Protocol;                                    *)
  989. (*                                                                      *)
  990. (*     Purpose:   Prompts remote user for, and reads, selected file     *)
  991. (*                transfer protocol.                                    *)
  992. (*                                                                      *)
  993. (*     Calling sequence:                                                *)
  994. (*                                                                      *)
  995. (*        Trans_Type := Get_Xfer_Protocol : Transfer_Type;              *)
  996. (*                                                                      *)
  997. (*           Trans_Type --- Protocol chosen by remote user.             *)
  998. (*                                                                      *)
  999. (*----------------------------------------------------------------------*)
  1000.  
  1001. VAR
  1002.    Trans_Mode        : AnyStr;
  1003.    Transfer_Protocol : Transfer_Type;
  1004.  
  1005. BEGIN (* Get_Xfer_Protocol *)
  1006.  
  1007.    REPEAT
  1008.  
  1009.       Host_Send_String( CR_LF_Host );
  1010.       Host_Prompt_And_Read_String('Enter transfer protocol (? for list): ',
  1011.                                      Trans_Mode, TRUE );
  1012.  
  1013.       Trans_Mode := Uppercase( TRIM( Trans_Mode ) );
  1014.  
  1015.       Transfer_Protocol := None;
  1016.  
  1017.       IF Trans_Mode = '?' THEN
  1018.          Display_Xfer_Protocols
  1019.       ELSE IF Trans_Mode = 'A'  THEN
  1020.          Transfer_Protocol := Ascii
  1021.       ELSE IF Trans_Mode = 'X'  THEN
  1022.          Transfer_Protocol := Xmodem_Chk
  1023.       ELSE IF Trans_Mode = 'XC' THEN
  1024.          Transfer_Protocol := Xmodem_CRC
  1025.       ELSE IF Trans_Mode = 'Y'  THEN
  1026.          Transfer_Protocol := Ymodem
  1027.       ELSE IF Trans_Mode = 'YB' THEN
  1028.          Transfer_Protocol := Ymodem_Batch
  1029.       ELSE IF Trans_Mode = 'T'  THEN
  1030.          Transfer_Protocol := Telink
  1031.       ELSE IF Trans_Mode = 'TC' THEN
  1032.          Transfer_Protocol := Telink
  1033.       ELSE IF Trans_Mode = 'M'  THEN
  1034.          Transfer_Protocol := Modem7_Chk
  1035.       ELSE IF Trans_Mode = 'MC'  THEN
  1036.          Transfer_Protocol := Modem7_CRC
  1037.       ELSE IF Trans_Mode = 'M7' THEN
  1038.          Transfer_Protocol := Modem7_CRC
  1039.       ELSE IF Trans_Mode = 'K' THEN
  1040.          BEGIN
  1041.             Transfer_Protocol    := Kermit;
  1042.             Kermit_File_Type_Var := Kermit_Ascii;
  1043.          END
  1044.       ELSE IF Trans_Mode = 'KB' THEN
  1045.          BEGIN
  1046.             Transfer_Protocol    := Kermit;
  1047.             Kermit_File_Type_Var := Kermit_Binary;
  1048.          END;
  1049.  
  1050.    UNTIL ( Transfer_Protocol <> None ) OR ( Trans_Mode = 'Q' );
  1051.  
  1052.    Get_Xfer_Protocol := Transfer_Protocol;
  1053.  
  1054. END   (* Get_Xfer_Protocol *);
  1055.  
  1056. (*----------------------------------------------------------------------*)
  1057. (*               Upload_A_File  --- Receive file from remote user       *)
  1058. (*----------------------------------------------------------------------*)
  1059.  
  1060. PROCEDURE Upload_A_File;
  1061.  
  1062. (*----------------------------------------------------------------------*)
  1063. (*                                                                      *)
  1064. (*     Procedure:  Upload_A_File;                                       *)
  1065. (*                                                                      *)
  1066. (*     Purpose:   Prompts remote user for, and receives, selected file. *)
  1067. (*                                                                      *)
  1068. (*     Calling sequence:                                                *)
  1069. (*                                                                      *)
  1070. (*        Upload_A_File;                                                *)
  1071. (*                                                                      *)
  1072. (*----------------------------------------------------------------------*)
  1073.  
  1074. VAR
  1075.    File_Name         : AnyStr;
  1076.    Trans_Mode        : AnyStr;
  1077.    Transfer_Protocol : Transfer_Type;
  1078.  
  1079. BEGIN (* Upload_A_File *)
  1080.  
  1081.    Host_Send_String( CR_LF_Host );
  1082.    Host_Prompt_And_Read_String('Enter file name to upload: ',
  1083.                                   File_Name, TRUE );
  1084.  
  1085.    Transfer_Protocol := Get_Xfer_Protocol;
  1086.    IF Transfer_Protocol = None THEN EXIT;
  1087.  
  1088.    IF ( Search_Xfer_List( File_Name ) ) THEN
  1089.       BEGIN
  1090.          Host_Send_String( CR_LF_Host );
  1091.          Host_Send_String_With_CR('File already exists, upload cancelled.');
  1092.       END
  1093.    ELSE IF( File_Name = 'PIBTERM.XFR' ) OR
  1094.           ( File_Name = 'PIBTERM.LOG' ) OR
  1095.           ( File_Name = 'PIBTERM.USF' ) OR
  1096.           ( File_Name = 'PIBTERM.MSG' ) OR
  1097.           ( File_Name = 'PIBTERM.CMT' ) THEN
  1098.       BEGIN
  1099.          Host_Send_String( CR_LF_Host );
  1100.          Host_Send_String_With_CR('You may not upload a file with that name.');
  1101.       END
  1102.    ELSE
  1103.       BEGIN                        (* FileName is global for transfers *)
  1104.          FileName := File_Name;
  1105.          Host_Send_String( CR_LF_Host );
  1106.          Host_Send_String_With_CR('Ready to receive file, begin your send procedure.');
  1107.          PibDownLoad( Transfer_Protocol );
  1108.       END;
  1109.  
  1110. END   (* Upload_A_File *);
  1111.  
  1112. (*----------------------------------------------------------------------*)
  1113. (*             Download_A_File  --- Send file to remote user            *)
  1114. (*----------------------------------------------------------------------*)
  1115.  
  1116. PROCEDURE Download_A_File;
  1117.  
  1118. (*----------------------------------------------------------------------*)
  1119. (*                                                                      *)
  1120. (*     Procedure:  Download_A_File;                                     *)
  1121. (*                                                                      *)
  1122. (*     Purpose:   Prompts remote user for, and sends, selected file.    *)
  1123. (*                                                                      *)
  1124. (*     Calling sequence:                                                *)
  1125. (*                                                                      *)
  1126. (*        Download_A_File;                                              *)
  1127. (*                                                                      *)
  1128. (*----------------------------------------------------------------------*)
  1129.  
  1130. VAR
  1131.    File_Name         : AnyStr;
  1132.    Trans_Mode        : AnyStr;
  1133.    Transfer_Protocol : Transfer_Type;
  1134.    Found_File        : BOOLEAN;
  1135.  
  1136. BEGIN (* Download_A_File *)
  1137.  
  1138.    Host_Send_String( CR_LF_Host );
  1139.    Host_Prompt_And_Read_String('Enter file name to download: ',
  1140.                                   File_Name, TRUE );
  1141.  
  1142.    Transfer_Protocol := Get_Xfer_Protocol;
  1143.    IF Transfer_Protocol = NONE THEN EXIT;
  1144.  
  1145.    IF POS( '*', File_Name ) = 0 THEN
  1146.       BEGIN
  1147.          Found_File := Search_Xfer_List( File_Name );
  1148.          IF ( NOT Found_File ) THEN
  1149.             BEGIN
  1150.                Host_Send_String( CR_LF_Host );
  1151.                Host_Send_String_With_CR('File not found, download cancelled.');
  1152.             END;
  1153.       END
  1154.    ELSE IF Transfer_Protocol IN [ Xmodem_Chk, Xmodem_Crc, Ascii, Ymodem ] THEN
  1155.       BEGIN
  1156.          Found_File := FALSE;
  1157.          Host_Send_String( CR_LF_Host );
  1158.          Host_Send_String('Wildcards are not allowed for this protocol.');
  1159.       END
  1160.    ELSE
  1161.       Found_File := TRUE;
  1162.  
  1163.    IF Found_File THEN
  1164.       BEGIN                        (* FileName is global for transfers *)
  1165.          FileName := File_Name;
  1166.          Host_Send_String( CR_LF_Host );
  1167.          Host_Send_String_With_CR('Ready to send, begin your receive procedure.');
  1168.          PibUpLoad( Transfer_Protocol );
  1169.       END;
  1170.  
  1171. END   (* Download_A_File *);
  1172.  
  1173. (*----------------------------------------------------------------------*)
  1174.  
  1175. BEGIN (* Process_File_Transfer_Commands *)
  1176.  
  1177.                                    (* No keyboard input yet *)
  1178.    Kbd_Input := FALSE;
  1179.                                    (* Stay in files section for a while *)
  1180.    Back := FALSE;
  1181.                                    (* Prompt for commands *)
  1182.    Display_Xfer_Commands;
  1183.                                    (* Wait for command to be entered *)
  1184.    REPEAT
  1185.       Done := Done OR ( NOT Host_Carrier_Detect );
  1186.    UNTIL Done OR Async_Receive( Ch ) OR KeyPressed;
  1187.  
  1188.                                    (* Process input from keyboard *)
  1189.    IF KeyPressed THEN
  1190.       BEGIN
  1191.          READ( KBD , Ch );
  1192.          Kbd_Input := TRUE;
  1193.          IF ( ORD( Ch ) = ESC ) AND KeyPressed THEN
  1194.             BEGIN
  1195.                READ( Kbd, Ch );
  1196.                IF ORD( Ch ) = F1 THEN
  1197.                   Ch := 'G'
  1198.                ELSE IF ORD( Ch ) = F2 THEN
  1199.                   Ch := 'Q';
  1200.             END;
  1201.       END;
  1202.  
  1203.    IF ( Not DONE ) THEN
  1204.                                    (* Echo command character *)
  1205.       IF Printer_On THEN
  1206.          WRITELN( Lst, Ch );
  1207.       IF Capture_On THEN
  1208.          WRITELN( Capture_File, Ch );
  1209.       Host_Send_String( Ch + CR_LF_Host );
  1210.  
  1211.                                    (* Process command request *)
  1212.       CASE UpCase( Ch ) OF
  1213.  
  1214.          'U':  Upload_A_File;
  1215.          'D':  Download_A_File;
  1216.          'Q':  BEGIN
  1217.                   IF Kbd_Input THEN
  1218.                      BEGIN
  1219.                         Host_Send_String_With_CR('System operator shutting ' +
  1220.                                                   ' down system.');
  1221.                         Host_Send_String_With_CR('Thanks for calling.');
  1222.                         Done := TRUE;
  1223.                      END
  1224.                   ELSE
  1225.                      BEGIN
  1226.                         Host_Send_String_With_CR('Quit and logoff');
  1227.                         Done := TRUE;
  1228.                      END;
  1229.                END;
  1230.          'L':  List_Files_For_Transfer;
  1231.          'X':  Expert_On := NOT Expert_On;
  1232.          'M':  BEGIN
  1233.                   Back         := TRUE;
  1234.                   Host_Section := 'M';
  1235.                END;
  1236.          'G':  IF Kbd_Input THEN
  1237.                   BEGIN
  1238.                      Host_Send_String_With_CR(' ... System operator wishes' +
  1239.                                                ' to chat, please wait ...');
  1240.                      Host_Send_String_With_CR(' ');
  1241.                      Gossip_Mode;
  1242.                   END;
  1243.  
  1244.          ELSE  Host_Send_String( ^G );
  1245.  
  1246.       END (* CASE *)
  1247.  
  1248. END   (* Process_File_Transfer_Commands *);
  1249.